package org.lds.logger.util;

import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveOutputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
import org.apache.commons.io.IOUtils;
import org.lds.logger.config.appender.rolling.compress.CompressType;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.file.Files;

/**
 * Apache Commons Compress
 */
public class CompressUtils {

    public static boolean compress(CompressType compressType, String source, String target) {
        if (compressType == CompressType.NONE) return true;

        if (compressType == CompressType.GZIP) {
            if (!target.endsWith(".gz")) {
                target += ".gz";
            }
            return gzipCompress(source, target);
        }

        if (!target.endsWith(".zip")) {
            target += ".zip";
        }
        return zipCompress(source, target);
    }

    /**
     * Gzip压缩
     *
     * @param source 要压缩的文件
     * @param target 压缩后的文件
     */
    public static boolean gzipCompress(String source, String target) {
        try (FileInputStream sourceInputStream = new FileInputStream(source);
             GzipCompressorOutputStream targetOutputStream = new GzipCompressorOutputStream(new FileOutputStream(target))) {
            IOUtils.copy(sourceInputStream, targetOutputStream);
            return true;
        } catch (Throwable e) {
            Utils.report("gzipCompress fail. error= " + e.getMessage());
            return false;
        }
    }

    /**
     * zip压缩
     *
     * @param source 要压缩的文件
     * @param target 压缩后的文件
     */
    public static boolean zipCompress(String source, String target) {
        File file = new File(source);

        try (ArchiveOutputStream o = new ZipArchiveOutputStream(new File(target))) {
            ArchiveEntry entry = new ZipArchiveEntry(target);
            o.putArchiveEntry(entry);

            try (InputStream i = Files.newInputStream(file.toPath())) {
                IOUtils.copy(i, o);
            }

            o.closeArchiveEntry();
            return true;
        } catch (Throwable e) {
            Utils.report("zipCompress fail. error= " + e.getMessage());
            return false;
        }
    }

}
